package pe.com.cotelasa.scp.dao.impl;

import java.io.Serializable;
import java.util.*;
import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import pe.com.cotelasa.common.dao.DaoImpl;
import pe.com.cotelasa.common.dao.excepcion.DAOException;
import pe.com.cotelasa.scp.dao.IDAODetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.dominio.common.ESTADO_REGISTRO;
import pe.com.cotelasa.scp.entidad.DetalleOrdenCompraServicio;
import pe.com.cotelasa.scp.entidad.OrdenCompraServicio;

/**
 * @author usuario
 */
@SuppressWarnings("unchecked")
@Repository("daoDetalleOrdenCompraServicio")
public class DAODetalleOrdenCompraServicioImpl extends DaoImpl<DetalleOrdenCompraServicio, Integer> implements IDAODetalleOrdenCompraServicio, Serializable {

    @Autowired
    private SessionFactory sessionFactory;

    @Transactional
    public List<DetalleOrdenCompraServicio> listarDetallesPorOrden(OrdenCompraServicio ordenCS) throws DAOException {
        List<DetalleOrdenCompraServicio> listaDetalles = new ArrayList<DetalleOrdenCompraServicio>();
        try {
            sessionFactory.getCurrentSession().flush();
            listaDetalles = sessionFactory.getCurrentSession().createCriteria(DetalleOrdenCompraServicio.class)
                    .addOrder(Order.asc("id"))
                    .add(Restrictions.like("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.eq("idOrdenCompraServicio", ordenCS))
                    .list();

        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }

        return listaDetalles;
    }

    @Transactional
    public List<DetalleOrdenCompraServicio> listarDetallesParaReporteOC(DetalleOrdenCompraServicio detalle, String ordenar, Date fechaInicio, Date fechaFinal) 
            throws DAOException {
        List<DetalleOrdenCompraServicio> listaDetalles = new ArrayList<DetalleOrdenCompraServicio>();
        String[] listaEstado = {"" + OrdenCompraServicio.ESTADO_ORDEN_SC.ABIERTO.getValor(),
            "" + OrdenCompraServicio.ESTADO_ORDEN_SC.CERRADO.getValor()};
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(DetalleOrdenCompraServicio.class)
                    .createAlias("idOrdenCompraServicio", "orden")
                    .createAlias("orden.idProveedor", "proveedor")
                    .createAlias("idArticulo", "art")
                    .add(Restrictions.eq("orden.idEmpresa", detalle.getIdOrdenCompraServicio().getIdEmpresa()))
                    .add(Restrictions.eq("orden.tipo", 'C'))
                    .add(Restrictions.in("orden.estadoOrden", listaEstado))
                    .add(Restrictions.like("art.nombreComercial", "%"+detalle.getIdArticulo().getNombreComercial()+"%"))
                    .add(Restrictions.like("proveedor.razonSocial", "%"+detalle.getIdOrdenCompraServicio().getIdProveedor().getRazonSocial()+"%"))
                    .add(Restrictions.like("orden.estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.like("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()));
            
            if(ordenar.equalsIgnoreCase("P")){
                query = query.addOrder(Order.asc("proveedor.razonSocial"));
            }else{
                query = query.addOrder(Order.asc("art.nombreComercial"));
            }
            query = query.addOrder(Order.asc("orden.fechaEmision"));
            
            if (fechaInicio == null && fechaFinal == null) {
                listaDetalles = query.list();
            } else if (fechaInicio != null && fechaFinal != null) {
                listaDetalles = query.add(Restrictions.ge("orden.fechaEmision", fechaInicio)).add(Restrictions.le("orden.fechaEmision", fechaFinal)).list();
            } else if (fechaInicio == null) {
                listaDetalles = query.add(Restrictions.le("orden.fechaEmision", fechaFinal)).list();
            } else if (fechaFinal == null) {
                listaDetalles = query.add(Restrictions.ge("orden.fechaEmision", fechaInicio)).list();
            }
            
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }

        return listaDetalles;
    }
    
    
    @Transactional
    public List<DetalleOrdenCompraServicio> listarDetallesParaReporteOS(DetalleOrdenCompraServicio detalle, String ordenar, Date fechaInicio, Date fechaFinal) 
            throws DAOException {
        List<DetalleOrdenCompraServicio> listaDetalles = new ArrayList<DetalleOrdenCompraServicio>();
        String[] listaEstado = {"" + OrdenCompraServicio.ESTADO_ORDEN_SC.ABIERTO.getValor(),
            "" + OrdenCompraServicio.ESTADO_ORDEN_SC.CERRADO.getValor()};
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(DetalleOrdenCompraServicio.class)
                    .createAlias("idOrdenCompraServicio", "orden")
                    .createAlias("orden.idProveedor", "proveedor")
                    .createAlias("idArticulo", "art")
                    .add(Restrictions.eq("orden.idEmpresa", detalle.getIdOrdenCompraServicio().getIdEmpresa()))
                    .add(Restrictions.eq("orden.tipo", 'S'))
                    .add(Restrictions.in("orden.estadoOrden", listaEstado))
                    .add(Restrictions.like("art.nombreComercial", "%"+detalle.getIdArticulo().getNombreComercial()+"%"))
                    .add(Restrictions.like("proveedor.razonSocial", "%"+detalle.getIdOrdenCompraServicio().getIdProveedor().getRazonSocial()+"%"))
                    .add(Restrictions.like("orden.servicio", "%"+detalle.getIdOrdenCompraServicio().getServicio()+"%"))
                    .add(Restrictions.like("orden.estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.like("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()));
            
            if(ordenar.equalsIgnoreCase("P")){
                query = query.addOrder(Order.asc("proveedor.razonSocial"));
            }else if(ordenar.equalsIgnoreCase("A")){
                query = query.addOrder(Order.asc("art.nombreComercial"));
            }else{
                query = query.addOrder(Order.asc("orden.servicio"));
            }
            query = query.addOrder(Order.asc("orden.fechaEmision"));
            
            if (fechaInicio == null && fechaFinal == null) {
                listaDetalles = query.list();
            } else if (fechaInicio != null && fechaFinal != null) {
                listaDetalles = query.add(Restrictions.ge("orden.fechaEmision", fechaInicio)).add(Restrictions.le("orden.fechaEmision", fechaFinal)).list();
            } else if (fechaInicio == null) {
                listaDetalles = query.add(Restrictions.le("orden.fechaEmision", fechaFinal)).list();
            } else if (fechaFinal == null) {
                listaDetalles = query.add(Restrictions.ge("orden.fechaEmision", fechaInicio)).list();
            }
            
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }

        return listaDetalles;
    }
    
    
    @Transactional
    public List<DetalleOrdenCompraServicio> buscarDetalleOrdenCSReporte(DetalleOrdenCompraServicio detalle, String[] listaEstado, Date fechaInicio, Date fechaFinal) 
            throws DAOException {
        List<DetalleOrdenCompraServicio> listaDetalles = new ArrayList<DetalleOrdenCompraServicio>();
        
        try {
            sessionFactory.getCurrentSession().flush();
            Criteria query = sessionFactory.getCurrentSession().createCriteria(DetalleOrdenCompraServicio.class)
                    .createAlias("idOrdenCompraServicio", "orden")
                    .createAlias("orden.idOrdenPedido", "op")
                    .add(Restrictions.eq("orden.idEmpresa", detalle.getIdOrdenCompraServicio().getIdEmpresa()))
                    .add(Restrictions.eq("orden.tipo", detalle.getIdOrdenCompraServicio().getTipo()))
                    .add(Restrictions.in("orden.estadoOrden", listaEstado))
                    .add(Restrictions.like("orden.estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()))
                    .add(Restrictions.eq("op.tipoOp", detalle.getIdOrdenCompraServicio().getIdOrdenPedido().getTipoOp()))
                    .add(Restrictions.like("estadoRegistro", ESTADO_REGISTRO.ACTIVO.getValor()));
            if (detalle.getIdOrdenCompraServicio().getIdOrdenPedido().getId() != null) {
                query = query.add(Restrictions.eq("idOrdenPedido", detalle.getIdOrdenCompraServicio().getIdOrdenPedido()));
            }

            query = query.addOrder(Order.asc("orden.fechaEmision"));
            
            if (fechaInicio == null && fechaFinal == null) {
                listaDetalles = query.list();
            } else if (fechaInicio != null && fechaFinal != null) {
                listaDetalles = query.add(Restrictions.ge("orden.fechaEmision", fechaInicio)).add(Restrictions.le("orden.fechaEmision", fechaFinal)).list();
            } else if (fechaInicio == null) {
                listaDetalles = query.add(Restrictions.le("orden.fechaEmision", fechaFinal)).list();
            } else if (fechaFinal == null) {
                listaDetalles = query.add(Restrictions.ge("orden.fechaEmision", fechaInicio)).list();
            }
            
        } catch (Exception e) {
            throw new DAOException(e.getMessage(), e);
        }

        return listaDetalles;
    }
    
}
